package th.stripes;

import able.stripes.JSP;
import com.google.inject.Inject;
import com.oas.thit._this.xsd.THISBaseDataElementBody;
import com.oas.thit._this.xsd.THISResponseBody;
import com.oas.thit.xmlmessage.xsd.Header;
import com.wideplay.warp.persist.Transactional;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBElement;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationMethod;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import th.dao.PenggunaDAO;
import th.manager.AkaunManager;
import th.manager.ResponseManager;
import th.manager.UserManager;
import th.model.Akaun;
import th.model.InfoAudit;
import th.model.Pengguna;
import th.service.session.LoginSession;
import th.service.session.SessionManager;
import th.stripes.action.DepositActionBean;
import th.stripes.webservice.WebServiceUtil;

@UrlBinding("/login")
public class LoginActionBean extends WelcomeActionBean {
   
//    @Validate(required=true, label="ID Pengguna")
    private String userLogin;
    @Validate(required=true, label="Kata Laluan")
    private String userPassword;    
    private Pengguna pguna; 
    private String imgid;
    private String secPhrase;

    @Inject PenggunaDAO penggunaDAO;
    @Inject UserManager userManager;
    @Inject AkaunManager akaunManager; 
    @Inject private ResponseManager responseManager;
    @Inject private WebServiceUtil webUtil;  
    
    private static final String VAL_ACC_MSG_ID = "TPUSRMGTWD03";
    
    private static final String VAL_ACC_TH_MSG_ID = "TPTH2TH3WD02";
    
    private static final String HEADER_ID_VAL_ACCOUNT = "THSACVL";
    
    private static final String HEADER_ID_VAL_TH_ACCOUNT = "THSQRAC";
    
    private static String SUCCESSFUL="0000";
    private static String SYSTEM_ERROR = "9999";
    private static String INVALID_ACC_STATUS = "5678";
    private static String STATUS_MATI = "M";
    private static String STATUS_BATAL = "Z";
    private static String ACC_STS_TIDAKSAH = "9000";
    private static String ACC_STS_BANKRUP = "9201";
    private static String ACC_STS_DORMAN = "9202";
    private static String ACC_STS_MATI = "9203";
    private static String ACC_STS_SULIT = "9204";
    private static String ACC_STS_TUTUP = "9205"; 
    private static String ACC_STS_EPF = "9206";
    
    private com.oas.thit._this.services.THISServices service = new com.oas.thit._this.services.THISServices();
    private com.oas.thit._this.services.THISServicesPortType port = service.getTHISServicesHttpSoap11Endpoint();
    private static Logger LOG = Logger.getLogger(DepositActionBean.class);
    
    
    @DontValidate
    public Resolution showForm() {
        return new JSP("login.jsp");
    }
    
    @DefaultHandler
    @DontValidate
    public Resolution showImageForm() {
        pguna  = userManager.findUserByIdUser(getUserLogin());        
        if(pguna==null){
            addSimpleError("Pengguna tidak wujud"); 
            return new JSP("home.jsp");
        } 
        
        imgid = pguna.getImgid();
        //addded in 3/6/2015
        secPhrase = pguna.getSecPhrase();
        //getContext().setCurrentUser(pguna);  
        setSenaraiIklan(iklanManager.senaraiIklan());
        return new JSP("login/home.jsp");
    }
    
    public Resolution login() {
        Pengguna pengguna = userManager.findUserByIdUser(getUserLogin(),"Y");       
        getContext().setCurrentUser(pengguna);   
//        pengguna.setTarikhAkhirLogin(new Date());
        pengguna.setBilanganCubaan(0); //set default balik
        userManager.updatePengguna(pengguna);  
        
        return new RedirectResolution(WelcomeActionBean.class);        
    }
    
    /*
     * Added in new validation : Check security phrase. If blank, force user to update 
     */
    @ValidationMethod
    @Transactional
    public void validate_login() {         
        
        Pengguna pguna = userManager.findUserByIdUser(getUserLogin(),"N");
        
        if (pguna != null) {
            imgid = pguna.getImgid();
            //addded in 3/6/2015
            secPhrase = pguna.getSecPhrase();
            if(pguna.getBilanganCubaan()>=3)
                addSimpleError("Akaun anda telah disekat. Sila tukar kata laluan.");
            else
                addSimpleError("Akaun tidak aktif. Sila tukar kata laluan.");
        } else if (!userManager.authenticate(getUserLogin(), getUserPassword())) {
            addSimpleError("ID Pengguna / Kata Laluan salah.");
            Pengguna pengguna = userManager.findUserByIdUser(getUserLogin(),"Y");
            imgid = pengguna.getImgid();
            //addded in 3/6/2015
            secPhrase = pengguna.getSecPhrase();
            if (pengguna != null) {
                int cubaan = (pengguna.getBilanganCubaan()== null?0:pengguna.getBilanganCubaan())+1;
                if (cubaan > 2) {
                    pengguna.setActive('N');       
                    addSimpleError("Akaun anda telah disekat. Sila tukar kata laluan.");
                }
                else {
                    String error = "ID Pengguna / Kata Laluan salah. ";
                    error = error+" Anda mempunyai";
                    int i = 3-cubaan;
                    error = " "+String.valueOf(i)+" kali cubaan sahaja lagi";
                    addSimpleError(error);
                }
                 pengguna.setBilanganCubaan(cubaan);
                 userManager.updatePengguna(pengguna);
            }
        } else {
            
            pguna = userManager.findUserByIdUser(getUserLogin(),"Y");
            if(pguna == null){
                addSimpleError("Pengguna tidak wujud.");
                return;
            }
            imgid = pguna.getImgid();
            //addded in 3/6/2015
            secPhrase = pguna.getSecPhrase();
            String noAkaun = akaunManager.getNoAkaun(pguna.getNoKp(), "Y");
           // String noKp = getNoKP(noAkaun); //--check noKp
            
            /*
             * If null/"" = set noKp kpd yg ade di mytaha
             * else, amik yg baru core. call updateKP()
             * 
             */
//            if (noKp == null || noKp.isEmpty()) {
//                noKp = pguna.getNoKp();
//            } 
            
            
            //validate user availability
            if (pguna.getJenisPengguna().getKod().equals("001")) { 
               String responseCode = "";
                try { // Call Web Service Operation
                    // TODO initialize WS operation arguments here
                    com.oas.thit._this.xsd.THISRequest req = new com.oas.thit._this.xsd.THISRequest();
                    // TODO process result here                
                    com.oas.thit._this.xsd.ObjectFactory objFactory = new com.oas.thit._this.xsd.ObjectFactory();
                    req.setHeader(webUtil.createHeader(VAL_ACC_MSG_ID, HEADER_ID_VAL_ACCOUNT));
                    THISBaseDataElementBody reqBody = objFactory.createTHISBaseDataElementBody();
                    

                    reqBody.setTHAcct(objFactory.createTHISBaseDataElementBodyTHAcct(noAkaun));
                    reqBody.setTHICNo(objFactory.createTHISBaseDataElementBodyTHICNo(pguna.getNoKp()));

                    JAXBElement<THISBaseDataElementBody> jReqBody = objFactory.createTHISRequestBody(reqBody);
                    req.setBody(jReqBody);

                    com.oas.thit._this.pin.xsd.AccountValidationResponse result = port.validateAccount(req);

                    Header header = result.getHeader().getValue();
                    responseCode = header.getResponseCode().getValue();
                    if (!responseCode.equals(SUCCESSFUL) && !responseCode.equals(ACC_STS_SULIT) && !responseCode.equals(ACC_STS_BANKRUP) && !responseCode.equals(ACC_STS_DORMAN) && !responseCode.equals(ACC_STS_EPF)) {
//                    AccountValidationResponseBody resp = result.getBody().getValue();
//                    if(resp.getTHAcctStatus()!=null && (resp.getTHAcctStatus().getValue().trim().equals(STATUS_MATI) || resp.getTHAcctStatus().getValue().trim().equals(STATUS_BATAL))){
//                        addSimpleError("" + responseManager.getResponseMessage(INVALID_ACC_STATUS ,VAL_ACC_MSG_ID));
                        addSimpleError("" + responseManager.getResponseMessage(ACC_STS_TIDAKSAH, VAL_ACC_MSG_ID));
                        return;
//                    }
                    }
                } catch (Exception ex) {
                    LOG.error(ex);
                    responseCode = SYSTEM_ERROR;
                    addSimpleError("" + responseManager.getResponseMessage(responseCode, VAL_ACC_MSG_ID));
                    return;
                }
            }
            
            
            SessionManager sm = SessionManager.getInstance();
            LoginSession ls = sm.getActiveSessionByUserId(getUserLogin());
             if (ls != null) {
                 addSimpleError("Pengguna \"" + getUserLogin() + "\" "
                            + "telah pun log masuk pada " + formatSDF(ls.getDateCreated()) + ". Sila klik Log Keluar untuk keluar "
                            + "dari sistem terlebih dahulu");
                 return;
             }
             
            HttpSession ses = context.getRequest().getSession();
            ses.setAttribute(th.stripes.config.ableActionBeanContext.USER_ID_KEY, getUserLogin());

            sm.addSession(ses.getId(), getUserLogin(), new Date(),
                    context.getRequest().getRemoteAddr(), context.getRequest().getRemoteHost());
            
            InfoAudit ia = new InfoAudit();
            ia.setDimasukOleh(pguna);
            ia.setTarikhMasuk(new Date());
            pguna.setBilanganCubaan(new Integer(0));
            userManager.updatePengguna(pguna);
       //     updateKP( noAkaun, noKp, pguna.getNoKp() ); //-- sync noKp : mytaha vs core
            context.getServletContext().setAttribute("save_count", new Integer(0));
        }        
    }
    
    
    private String getNoKP( String noAkaun) {
        //new validation
        
        try { // Call Web Service Operation            
            // TODO initialize WS operation arguments here
            com.oas.thit._this.queryacct.xsd.ObjectFactory objFactory 
                    = new com.oas.thit._this.queryacct.xsd.ObjectFactory();
            com.oas.thit._this.queryacct.xsd.QueryAccountRequest req 
                    = new com.oas.thit._this.queryacct.xsd.QueryAccountRequest();
            req.setHeader(webUtil.createHeader(VAL_ACC_TH_MSG_ID, HEADER_ID_VAL_TH_ACCOUNT));
            
            com.oas.thit._this.queryacct.xsd.QueryAccountRequestBody reqBody = objFactory.createQueryAccountRequestBody();
            
            reqBody.setTHAcct(objFactory.createQueryAccountRequestBodyTHAcct(noAkaun));            
            
            req.setBody(objFactory.createQueryAccountRequestBody(reqBody));
            
            // TODO process result here
            com.oas.thit._this.xsd.THISResponse result = port.queryAccount(req);
            
            Header header = result.getHeader().getValue();
            String responseCode = header.getResponseCode().getValue();
            if ( responseCode.equals(SUCCESSFUL) ) {
                THISResponseBody res = result.getBody().getValue();
                return StringUtils.isNotBlank(res.getTHICNo().getValue()) ? res.getTHICNo().getValue() : "" ;
                        
                
//                List<Akaun> senaraiAkauns = pguna.getSenaraiAkaun();
//                List<Akaun> updateAkauns = new ArrayList<Akaun>();
//                for (Akaun akaun : senaraiAkauns) {
//                    akaun.set
//                }
            }
            
        } catch (Exception ex) {
            // TODO handle custom exceptions here
        }
        return null;
    }
    
    private void updateKP (String noAkaun, String noKp, String oldKp) {
        if (!noKp.equals(oldKp)) {
            userManager.updatePengguna(noAkaun, noKp, oldKp);
        }
    }
    
    private String formatSDF(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        return sdf.format(date);
    }

    public String getUserLogin() {
        return userLogin;
    }

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public Pengguna getPguna() {
        return pguna;
    }

    public void setPguna(Pengguna pguna) {
        this.pguna = pguna;
    }

    public String getImgid() {
        return imgid;
    }

    public void setImgid(String imgid) {
        this.imgid = imgid;
    }

    public String getSecPhrase() {
        return secPhrase;
    }

    public void setSecPhrase(String secPhrase) {
        this.secPhrase = secPhrase;
    }
    
    
   

}
